package com.jsj.seafile.realApi;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.jsj.seafile.apiInterface.ApiInterface;
import com.jsj.seafile.entity.UploadFileRes;
import okhttp3.*;


import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.*;
import java.util.List;


public class realService implements ApiInterface, Serializable {

    private String SERVICE_URL;
    private String FILE_SERVER_ROOT;
    private String FILE_UP_LINK;
    private String FILE_UP_URL;
    public realService(String SERVICE_URL, String FILE_SERVER_ROOT, String FILE_UP_LINK, String FILE_UP_URL){
        this.SERVICE_URL=SERVICE_URL;
        this.FILE_SERVER_ROOT=FILE_SERVER_ROOT;
        this.FILE_UP_LINK=FILE_UP_LINK;
        this.FILE_UP_URL=FILE_UP_URL;
    }

    public realService() {
    }

    @Override
    public boolean getDirDeatil(OkHttpClient client,String token,String repo_id,String p){
        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Authorization","Token "+token)
                .header("Accept","application/json")
                .header("indent","4")
                .url(SERVICE_URL+"/api/v2.1/repos/"+repo_id+"/dir/detail/?path="+p)
                .get()
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                return true;
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public String obtainAuthToken(OkHttpClient client, String username, String password) {
        RequestBody body=new FormBody.Builder()
                .add("username",username)
                .add("password",password)
                .build();
        Request request=new Request.Builder()
                .url(SERVICE_URL+"/api2/auth-token/")
                .header("Content-Type","application/x-www-form-urlencoded")
                .post(body)
                .build();
        try (Response response=client.newCall(request).execute()){
            JSONObject jObj =parseJson(response.body().string());
            return jObj.getString("token");
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getUploadLink(OkHttpClient client, String token, String repo_id, String p) {
        System.out.println("未命中");
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        builder.addFormDataPart("path",p);
        builder.addFormDataPart("repo_id",repo_id);
        RequestBody body=builder.build();
        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Authorization","Token "+token)
                .header("Accept","application/json")
                .header("indent","4")
                .url(SERVICE_URL+"/api/v2.1/upload-links/")
                .post(body)
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                return response.body().string();
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }

        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getUploadF(OkHttpClient client, String token) {
        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Accept","application/json")
                .header("indent","4")
                .url(SERVICE_URL +"/api/v2.1/upload-links/"+token+"/upload/")
                .get()
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                return response.body().string();
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<UploadFileRes> uploadFile(OkHttpClient client, String token, String uploadLink, String parent_dir, String relative_path, File... files) {
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);

        for (File file:files){
            builder.addFormDataPart("file",file.getName(),RequestBody.create(MediaType.parse("application/octet-stream"), file));
        }

        builder.addFormDataPart("parent_dir",parent_dir);
        builder.addFormDataPart("relative_path",relative_path);
        RequestBody body=builder.build();

        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Authorization","Token "+token)
                .post(body)
                .url(uploadLink+"?ret-json=1")
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                return JSONObject.parseArray(response.body().string(),UploadFileRes.class);
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getDownLoadLink(OkHttpClient client, String token, String repo_id, String p) {
        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Authorization","Token "+token)
                .header("Accept","application/json")
                .header("charset","utf-8")
                .header("indent","4")
                .url(SERVICE_URL+"/api2/repos/"+repo_id+"/file/?p="+p+"&reuse=1")
                .get()
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                return response.body().string().replaceAll("\"","");
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public boolean realDownload(OkHttpClient client, String realLink, String p) {
        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Accept","application/json")
                .header("charset","utf-8")
                .header("indent","4")
                .url(realLink)
                .get()
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                //转化成byte数组
                byte[] bytes = response.body().bytes();
                //本地文件夹目录（下载位置）
                String folder = p;
                String filename = realLink.substring(realLink.lastIndexOf("/")+1);
                System.out.println(filename);
                Path folderPath = Paths.get(folder);
                boolean desk = Files.exists(folderPath);
                if (!desk) {
                    //不存在文件夹 => 创建
                    Files.createDirectories(folderPath);
                }
                Path filePath = Paths.get(folder + filename);
                boolean exists = Files.exists(filePath, LinkOption.NOFOLLOW_LINKS);
                if (!exists) {
                    //不存在文件 => 创建
                    Files.write(filePath, bytes, StandardOpenOption.CREATE);
                }
                return true;
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public String getDirDownloadToken(OkHttpClient client, String token, String repo_id, String parent_dir, String DirToken, List<String> dirents) {
        JSONObject jsonObject=new JSONObject();
        JSONArray jsonArray=new JSONArray();
        jsonObject.put("token",DirToken);
        jsonObject.put("parent_dir",parent_dir);
        for(String dirent:dirents){
            jsonArray.add(dirent);
        }
        jsonObject.put("dirents",jsonArray);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), String.valueOf(jsonObject));
        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Authorization","Token "+token)
                .header("Accept","application/json")
                .header("indent","4")
                .url(SERVICE_URL+"/api/v2.1/share-link-zip-task/")
                .post(requestBody)
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                return JSONObject.parseObject(response.body().string()).getString("zip_token");
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public boolean queryZipProgress(OkHttpClient client, String token, String zipDownloadToken) {
        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Authorization","Token "+token)
                .header("Accept","application/json")
                .header("indent","4")
                .url(SERVICE_URL+"/api/v2.1/query-zip-progress/?token="+zipDownloadToken)
                .get()
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                String temp=response.body().string();
                if(JSONObject.parseObject(temp).getString("zipped").equals(
                        JSONObject.parseObject(temp).getString("total")
                )){
                    return true;
                }else {
                    return false;
                }
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public String  CreateZipDownLink(OkHttpClient client,String token,String p,String repo_id){
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        builder.addFormDataPart("repo_id",repo_id);
        builder.addFormDataPart("path",p);
        RequestBody body=builder.build();
        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Authorization","Token "+token)
                .header("Accept","application/json")
                .header("charset","utf-8")
                .header("indent","4")
                .url(SERVICE_URL+"/api/v2.1/share-links/")
                .post(body)
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                return response.body().string();
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getZipDownLink(OkHttpClient client,String token,String p,String repo_id){
        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Authorization","Token "+token)
                .header("Accept","application/json")
                .header("charset","utf-8")
                .header("indent","4")
                .url(SERVICE_URL+"/api/v2.1/share-links/?repo_id="+repo_id+"&path"+p)
                .get()
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                return response.body().string();
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getRealZipLink(OkHttpClient client, String token, String zipDownloadToken) {
        if(queryZipProgress(client,token,zipDownloadToken)){
            return SERVICE_URL+"/seafhttp/zip/"+zipDownloadToken;
        }
        return null;
    }

    @Override
    public String getDirDownloadLink(OkHttpClient client, String token, String dirDownloadToken) {
        if(queryZipProgress(client,token,dirDownloadToken)){
            return FILE_SERVER_ROOT+"zip/"+dirDownloadToken;
        }
        return null;
    }

    @Override
    public boolean createNewDir(OkHttpClient client, String token, String repo_id, String p) {
        RequestBody body=new FormBody.Builder()
                .add("operation","mkdir")
                .build();
        Request request=new Request.Builder()
                .header("Content-Type","application/x-www-form-urlencoded")
                .header("Authorization","Token "+token)
                .header("Accept","application/json")
                .header("indent","4")
                .url(SERVICE_URL+"/api2/repos/"+repo_id+"/dir/?p="+p)
                .post(body)
                .build();
        try (Response response=client.newCall(request).execute()){
            if (response.isSuccessful()){
                return true;
            }else {
                System.out.println(response.code());
                System.out.println(response.body().string());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return false;
    }


    public String teztcache(int id){
        System.out.println("未命中");
        return "1";
    }



    private JSONObject parseJson(String jsonStr){
        //show the json Str for test
//        System.out.println(jsonStr);
        return JSON.parseObject(jsonStr, Feature.AutoCloseSource);
    }
}
